package com.waikuai.shop.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.waikuai.shop.common.result.Result;
import com.waikuai.shop.service.UserFavoriteService;
import com.waikuai.shop.service.UserService;
import com.waikuai.shop.util.JwtUtil;
import com.waikuai.shop.vo.ProductSimpleVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 用户收藏控制器
 * @author waikuai
 */
@Slf4j
@RestController
@RequestMapping("/favorites")
@RequiredArgsConstructor
@Validated
public class UserFavoriteController {

    private final UserFavoriteService userFavoriteService;
    private final UserService userService;
    private final JwtUtil jwtUtil;

    /**
     * 获取用户收藏列表（分页）
     */
    @GetMapping
    public Result<IPage<ProductSimpleVO>> getFavorites(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "20") Integer size,
            HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            
            // 获取所有收藏列表
            List<ProductSimpleVO> allFavorites = userFavoriteService.getUserFavorites(userId);
            
            // 手动分页
            int total = allFavorites.size();
            int start = (current - 1) * size;
            int end = Math.min(start + size, total);
            
            Page<ProductSimpleVO> page = new Page<>(current, size, total);
            if (start < total) {
                List<ProductSimpleVO> pageRecords = allFavorites.subList(start, end);
                page.setRecords(pageRecords);
            }
            
            log.info("获取用户收藏列表成功，用户ID: {}, 页码: {}, 页大小: {}, 总数: {}", userId, current, size, total);
            return Result.success("获取收藏列表成功", page);
        } catch (Exception e) {
            log.error("获取用户收藏列表失败: {}", e.getMessage(), e);
            return Result.error("获取收藏列表失败");
        }
    }

    /**
     * 添加收藏
     */
    @PostMapping("/add")
    public Result<String> addFavorite(@RequestBody java.util.Map<String, Object> requestBody,
                                      HttpServletRequest request) {
        Long productId = null;
        if (requestBody.get("productId") instanceof Number) {
            productId = ((Number) requestBody.get("productId")).longValue();
        } else if (requestBody.get("productId") != null) {
            productId = Long.parseLong(requestBody.get("productId").toString());
        }
        if (productId == null) {
            return Result.error("商品ID不能为空");
        }
        try {
            Long userId = getCurrentUserId(request);
            boolean result = userFavoriteService.addToFavorites(userId, productId);
            
            if (result) {
                log.info("添加收藏成功，用户ID: {}, 商品ID: {}", userId, productId);
                return Result.success("添加收藏成功");
            } else {
                return Result.error("添加收藏失败，商品可能不存在或已收藏");
            }
        } catch (Exception e) {
            log.error("添加收藏失败: {}", e.getMessage(), e);
            return Result.error("添加收藏失败");
        }
    }

    /**
     * 取消收藏
     */
    @DeleteMapping("/{productId}")
    public Result<String> removeFavorite(@PathVariable Long productId,
                                        HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            boolean result = userFavoriteService.removeFromFavorites(userId, productId);
            
            if (result) {
                log.info("取消收藏成功，用户ID: {}, 商品ID: {}", userId, productId);
                return Result.success("取消收藏成功");
            } else {
                return Result.error("取消收藏失败");
            }
        } catch (Exception e) {
            log.error("取消收藏失败: {}", e.getMessage(), e);
            return Result.error("取消收藏失败");
        }
    }

    /**
     * 切换收藏状态
     */
    @PostMapping("/toggle")
    public Result<Boolean> toggleFavorite(@RequestBody java.util.Map<String, Object> requestBody,
                                          HttpServletRequest request) {
        Long productId = null;
        if (requestBody.get("productId") instanceof Number) {
            productId = ((Number) requestBody.get("productId")).longValue();
        } else if (requestBody.get("productId") != null) {
            productId = Long.parseLong(requestBody.get("productId").toString());
        }
        if (productId == null) {
            return Result.error("商品ID不能为空");
        }
        try {
            Long userId = getCurrentUserId(request);
            userFavoriteService.toggleFavorite(userId, productId);
            boolean isFavorited = userFavoriteService.isFavorited(userId, productId);
            
            log.info("切换收藏状态成功，用户ID: {}, 商品ID: {}, 当前状态: {}", userId, productId, isFavorited);
            return Result.success(isFavorited ? "已收藏" : "已取消收藏", isFavorited);
        } catch (RuntimeException e) {
            // 用户未登录的特殊处理
            if (e.getMessage() != null && e.getMessage().contains("未登录")) {
                log.warn("用户未登录，无法切换收藏状态");
                return Result.error("请先登录后再进行收藏操作");
            }
            log.error("切换收藏状态失败: {}", e.getMessage(), e);
            return Result.error(e.getMessage() != null ? e.getMessage() : "切换收藏状态失败");
        } catch (Exception e) {
            log.error("切换收藏状态失败: {}", e.getMessage(), e);
            return Result.error("切换收藏状态失败");
        }
    }

    /**
     * 检查是否已收藏
     */
    @GetMapping("/check/{productId}")
    public Result<Boolean> checkFavorite(@PathVariable Long productId,
                                         HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            boolean isFavorited = userFavoriteService.isFavorited(userId, productId);
            
            log.info("检查收藏状态，用户ID: {}, 商品ID: {}, 是否已收藏: {}", userId, productId, isFavorited);
            return Result.success("查询成功", isFavorited);
        } catch (RuntimeException e) {
            // 用户未登录时，返回未收藏状态
            if (e.getMessage() != null && e.getMessage().contains("未登录")) {
                log.debug("用户未登录，返回未收藏状态");
                return Result.success("查询成功", false);
            }
            log.error("检查收藏状态失败: {}", e.getMessage(), e);
            return Result.error("检查收藏状态失败");
        } catch (Exception e) {
            log.error("检查收藏状态失败: {}", e.getMessage(), e);
            return Result.error("检查收藏状态失败");
        }
    }

    /**
     * 获取收藏数量
     */
    @GetMapping("/count")
    public Result<Integer> getFavoriteCount(HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            Integer count = userFavoriteService.countUserFavorites(userId);
            
            log.info("获取收藏数量成功，用户ID: {}, 数量: {}", userId, count);
            return Result.success("查询成功", count);
        } catch (Exception e) {
            log.error("获取收藏数量失败: {}", e.getMessage(), e);
            return Result.error("获取收藏数量失败");
        }
    }

    /**
     * 批量取消收藏
     */
    @DeleteMapping("/batch")
    public Result<String> batchRemoveFavorites(@RequestBody List<Long> productIds,
                                               HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            boolean result = userFavoriteService.batchRemoveFromFavorites(userId, productIds);
            
            if (result) {
                log.info("批量取消收藏成功，用户ID: {}, 数量: {}", userId, productIds.size());
                return Result.success("批量取消收藏成功");
            } else {
                return Result.error("批量取消收藏失败");
            }
        } catch (Exception e) {
            log.error("批量取消收藏失败: {}", e.getMessage(), e);
            return Result.error("批量取消收藏失败");
        }
    }

    /**
     * 清空所有收藏
     */
    @DeleteMapping("/clear")
    public Result<String> clearFavorites(HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            boolean result = userFavoriteService.clearFavorites(userId);
            
            if (result) {
                log.info("清空收藏成功，用户ID: {}", userId);
                return Result.success("清空收藏成功");
            } else {
                return Result.error("清空收藏失败");
            }
        } catch (Exception e) {
            log.error("清空收藏失败: {}", e.getMessage(), e);
            return Result.error("清空收藏失败");
        }
    }

    /**
     * 获取当前登录用户ID
     * 优先使用Spring Security认证，如果不可用则从HTTP Token中获取
     */
    private Long getCurrentUserId() {
        // 尝试从Spring Security获取
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.getPrincipal() != null) {
                Object principal = authentication.getPrincipal();
                if (principal instanceof UserDetails) {
                    UserDetails userDetails = (UserDetails) principal;
                    String username = userDetails.getUsername();
                    
                    com.waikuai.shop.entity.User user = userService.findByUsername(username);
                    if (user != null) {
                        return user.getId();
                    }
                }
            }
        } catch (Exception e) {
            log.debug("从Spring Security获取用户ID失败，尝试从Token获取: {}", e.getMessage());
        }
        
        // 如果Spring Security不可用，抛出异常（需要在调用处传入HttpServletRequest）
        throw new RuntimeException("用户未登录，请先登录");
    }

    /**
     * 从HTTP请求中获取用户ID（备用方案）
     */
    private Long getUserIdFromToken(HttpServletRequest request) {
        try {
            String bearerToken = request.getHeader("Authorization");
            if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
                String token = bearerToken.substring(7); // 移除 "Bearer " 前缀
                
                // 验证token格式
                if (!jwtUtil.validateTokenFormat(token)) {
                    log.warn("Token格式无效");
                    return null;
                }
                
                // 检查token是否过期
                if (jwtUtil.isTokenExpired(token)) {
                    log.warn("Token已过期");
                    return null;
                }
                
                // 从token中提取用户ID
                Long userId = jwtUtil.getUserIdFromToken(token);
                if (userId != null) {
                    log.debug("从Token中获取用户ID成功: {}", userId);
                    return userId;
                }
            }
        } catch (Exception e) {
            log.error("从Token中获取用户ID失败: {}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取当前登录用户ID（兼容多种方式）
     */
    private Long getCurrentUserId(HttpServletRequest request) {
        try {
            return getCurrentUserId();
        } catch (RuntimeException e) {
            // 如果Spring Security方式失败，尝试从Token获取
            Long userId = getUserIdFromToken(request);
            if (userId != null) {
                return userId;
            }
            // 如果都失败，抛出更明确的异常
            log.warn("获取用户ID失败: Spring Security和Token都不可用");
            throw new RuntimeException("用户未登录，请先登录");
        }
    }
}

